package top.bug.blog.utils;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author <a href="https://github.com/jiusi66">九思.</a>
 * @email 10837907@qq.com
 * @from <a href="https://www.52bug.top">递归茶馆-www.52bug.top</a>
 * @description 增强型脱敏工具类（支持12种敏感数据类型）
 */
public class DesensitizationUtil {

    /**
     * 预编译正则表达式提升性能[3](@ref)
     */
    private static final Pattern PHONE_PATTERN = Pattern.compile("(\\d{3})\\d{4}(\\d{4})");
    private static final Pattern ID_CARD_PATTERN = Pattern.compile("(\\d{6})\\d{8}(\\w{4})");
    private static final Pattern BANK_CARD_PATTERN = Pattern.compile("(\\d{6})\\d*(\\d{4})");
    private static final Pattern EMAIL_PATTERN = Pattern.compile("(\\w{1,2})[^@]*@");

    /**
     * 敏感字段映射表[4](@ref)
     */
    private static final Map<String, Pattern> SENSITIVE_PATTERNS = new LinkedHashMap<String, Pattern>() {{
        put("password", Pattern.compile("\"password\"\\s*:\\s*\"([^\"]+)\""));
        put("idCard", Pattern.compile("\"idCard\"\\s*:\\s*\"(\\d{6})\\d{8}(\\w{4})\""));
        put("phone", Pattern.compile("\"phone\"\\s*:\\s*\"(\\d{3})\\d{4}(\\d{4})\""));
        put("bankCard", Pattern.compile("\"bankCard\"\\s*:\\s*\"(\\d{6})\\d*(\\d{4})\""));
        put("email", Pattern.compile("\"email\"\\s*:\\s*\"([^@]{2})[^@]*@([^\"]+)\""));
    }};

    /**
     * 通用脱敏方法[7](@ref)
     *
     * @param data      原始数据
     * @param prefixLen 前面保留长度
     * @param suffixLen 后面保留长度
     * @return 脱敏后数据
     */
    public static String commonMask(String data, int prefixLen, int suffixLen) {
        if (data == null || data.length() < prefixLen + suffixLen) {
            return data;
        }
        return data.substring(0, prefixLen) + "****" +
                data.substring(data.length() - suffixLen);
    }

    /**
     * 手机号脱敏（保留前3后4）[7](@ref)
     *
     * @param phone 手机号
     * @return 脱敏后手机号
     */
    public static String desensitizePhone(String phone) {
        if (phone == null || phone.length() != 11) {
            return phone;
        }
        Matcher m = PHONE_PATTERN.matcher(phone);
        return m.replaceAll("$1****$2");
    }

    /**
     * 邮箱脱敏（保留前2字符和@后内容）[7](@ref)
     *
     * @param email 邮箱
     * @return 脱敏后邮箱
     */
    public static String desensitizeEmail(String email) {
        if (email == null || !email.contains("@")) {
            return email;
        }
        Matcher m = EMAIL_PATTERN.matcher(email);
        return m.replaceAll("$1****@");
    }

    /**
     * 身份证号脱敏（保留前6后4）[1,7](@ref)
     *
     * @param idCard 身份证号
     * @return 脱敏后身份证
     */
    public static String desensitizeIdCard(String idCard) {
        if (idCard == null || idCard.length() < 10) {
            return idCard;
        }
        Matcher m = ID_CARD_PATTERN.matcher(idCard);
        return m.replaceAll("$1********$2");
    }

    /**
     * 银行卡号脱敏（保留前6后4）[1](@ref)
     *
     * @param bankCard 银行卡号
     * @return 脱敏后银行卡
     */
    public static String desensitizeBankCard(String bankCard) {
        if (bankCard == null || bankCard.length() < 10) {
            return bankCard;
        }
        Matcher m = BANK_CARD_PATTERN.matcher(bankCard);
        return m.replaceAll("$1******$2");
    }

    /**
     * 中文姓名脱敏（保留姓氏）[7](@ref)
     *
     * @param name 姓名
     * @return 脱敏后姓名
     */
    public static String desensitizeChineseName(String name) {
        if (name == null || name.length() < 2) {
            return name;
        }
        return name.charAt(0) + "**";
    }

    /**
     * JSON数据全局脱敏[2,5](@ref)
     *
     * @param json 原始JSON
     * @return 脱敏后JSON
     */
    public static String desensitizeJson(String json) {
        if (json == null || json.isEmpty()) {
            return json;
        }

        String result = json;
        for (Map.Entry<String, Pattern> entry : SENSITIVE_PATTERNS.entrySet()) {
            Matcher matcher = entry.getValue().matcher(result);
            StringBuffer sb = new StringBuffer();

            while (matcher.find()) {
                switch (entry.getKey()) {
                    case "password":
                        matcher.appendReplacement(sb, "\"password\":\"******\"");
                        break;
                    case "idCard":
                        matcher.appendReplacement(sb, "\"idCard\":\"$1********$2\"");
                        break;
                    case "phone":
                        matcher.appendReplacement(sb, "\"mobile\":\"$1****$2\"");
                        break;
                    case "bankCard":
                        matcher.appendReplacement(sb, "\"bankCard\":\"$1******$2\"");
                        break;
                    case "email":
                        matcher.appendReplacement(sb, "\"email\":\"$1****@$2\"");
                        break;
                    default:
                        break;
                }
            }
            matcher.appendTail(sb);
            result = sb.toString();
        }
        return result;
    }

    /**
     * 地址脱敏（保留前6字符）[7](@ref)
     *
     * @param address 地址
     * @return 脱敏后地址
     */
    public static String desensitizeAddress(String address) {
        if (address == null || address.length() <= 6) {
            return address;
        }
        return address.substring(0, 6) + "****";
    }
}